/******************************************************************************* * Copyright (c) 2002, 2006 GEBIT Gesellschaft fuer EDV-Beratung * und Informatik-Technologien mbH, * Berlin, Duesseldorf, Frankfurt (Germany) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation * IBM Corporation - bug 24108 *******************************************************************************/ package org.eclipse.ant.internal.ui.editor.tools; import java.io.IOException; import java.net.URL; import com.ibm.icu.text.MessageFormat; import java.util.Vector; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.ant.internal.ui.AntUIPlugin; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * This class can be used to merge the tasks.xml and XDOCtasks.xml. * These files can be found in the Ant Editor Content Assist Dev folder. * Move the files to the Ant Editor folder to use this class. * * The xml automatically generated from the proposed xdoclet in the Apache Ant's * project currently has no information on required attributes. In the future the task writers * hopefully will include this information in the source code comments. Our * template currently inserts an attribute required="NOTDEFINED" and this class * replaces that field if its defined in the xml file we have generated from the * information based on the html files in the Apache Ant's manual directory. */ public class TaskXMLFileMerger { //Definitions for the HTML Generated XML File public static String HTML_TASKS_DESCRIPTION_XML_FILE_NAME = "/tasks.xml"; //$NON-NLS-1$ public static String HTML_XML_TAG_TASKS = "TASKS"; //$NON-NLS-1$ public static String HTML_XML_TAG_TASK = "TASK"; //$NON-NLS-1$ public static String HTML_XML_TAG_ATTRIBUTE = "ATTRIBUTE"; //$NON-NLS-1$ //public static String HTML_XML_TAG_DESCRIPTION = "DESCRIPTION"; public static String HTML_XML_ATTRIBUTE_NAME = "NAME"; //$NON-NLS-1$ public static String HTML_XML_ATTRIBUTE_REQUIRED = "REQUIRED"; //$NON-NLS-1$ //Definitions for the XDoclet Genereated XML File public static String XDOC_TASKS_DESCRIPTION_XML_FILE_NAME = "/XDOCtasks.xml"; //$NON-NLS-1$ public static String XDOC_XML_TAG_TASKS = "tasks"; //$NON-NLS-1$ public static String XDOC_XML_TAG_TASK = "task"; //$NON-NLS-1$ public static String XDOC_XML_TAG_NAME = "name"; //$NON-NLS-1$ public static String XDOC_XML_TAG_STRUCTURE = "structure"; //$NON-NLS-1$ public static String XDOC_XML_TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$ public static String XDOC_XML_TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$ public static String XDOC_XML_TAG_ELEMENTS = "elements"; //$NON-NLS-1$ public static String XDOC_XML_TAG_ELEMENT = "element"; //$NON-NLS-1$ public static String XDOC_XML_TAG_REQUIRED = "required"; //$NON-NLS-1$ protected NodeList taskNodes_HTML = null; protected NodeList taskNodes_XDOC = null; public Document xdocXMLDocument = null; /** * Creates an initialized instance. */ public TaskXMLFileMerger() { initialize(); } /** * Parses the task description xml files and stores the information. */ private void initialize() { Document tmpDocument = null; //Get All the Tasks in the HTML XML Generated file and store in the taskNodes_HTML tmpDocument = parseFile(HTML_TASKS_DESCRIPTION_XML_FILE_NAME); taskNodes_HTML = tmpDocument.getFirstChild().getChildNodes(); //Do the same for the XDOC XML Generated file tmpDocument = parseFile(XDOC_TASKS_DESCRIPTION_XML_FILE_NAME); taskNodes_XDOC = tmpDocument.getFirstChild().getChildNodes(); xdocXMLDocument = tmpDocument; /* Document tempDocument = parseFile(aFileName); Node tempRootNode = tempDocument.getDocumentElement(); NodeList tempChildNodes = tempRootNode.getChildNodes(); for(int i=0; i<tempChildNodes.getLength(); i++) { Node tempNode = tempChildNodes.item(i); if(tempNode.getNodeType() == Node.ELEMENT_NODE) { String tempTagName = tempNode.getNodeName(); if(tempTagName.equals(anXML_TAG_TASK)) { NamedNodeMap tempAttributes = tempNode.getAttributes(); Node tempAttributeNode = tempAttributes.getNamedItem(anXML_ATTRIBUTE_NAME); if(tempAttributeNode != null) { String tempTaskName = tempAttributeNode.getNodeValue(); if(tempTaskName != null) { aHashMap.put(tempTaskName, tempNode); } } } } } */ } /** * This is the function that does all the work. Calling this * will cause all Required fields in all Attributes in the * XMLDoc file to be replaced with the value in the corresponding * Attributes Required field in the HTML Xml file. */ public void runReplaceAttributeRequiredProcess() { //Iterate over all the tasks. If task is found in sourceList, //then iterate over all the attributes, try to find out if the //the attribute is required. for(int i = 0; i < taskNodes_XDOC.getLength(); ++i ) { Node tmpTargetNode = taskNodes_XDOC.item(i); if(tmpTargetNode.getNodeType() == Node.ELEMENT_NODE ) { replaceAttributeRequiredInTaskNode(tmpTargetNode); } } } private void replaceAttributeRequiredInTaskNode(Node aTargetTaskNode) { String tmpTaskName = aTargetTaskNode.getAttributes().getNamedItem(XDOC_XML_TAG_NAME).getNodeValue(); if(tmpTaskName != null ) { Node tmpSourceNode = getTaskInHTMLGeneratedTaskListNamed(tmpTaskName); if(tmpSourceNode != null) { replaceAttributeRequiredInXMLTaskNodeWithAttributeRequiredInHTMLNode(aTargetTaskNode, tmpSourceNode); } else { System.out.println(MessageFormat.format("Did not find Task \"{0}\" in HTML XML file.", new String[]{tmpTaskName})); //$NON-NLS-1$ } } else { System.out.println(MessageFormat.format("Did not find TaskName in TargetTaskNode: {0}", new String[]{aTargetTaskNode.toString()})); //$NON-NLS-1$ } } private Node getTaskInHTMLGeneratedTaskListNamed(String aTaskName) { for(int i = 0; i<taskNodes_HTML.getLength(); ++i ) { Node tmpTaskNode = taskNodes_HTML.item(i); if(tmpTaskNode.getNodeType() == Node.ELEMENT_NODE ) { String tmpTagName = tmpTaskNode.getNodeName(); if(tmpTagName.equals(HTML_XML_TAG_TASK)) { NamedNodeMap tmpMap = tmpTaskNode.getAttributes(); Node tmpNameNode = tmpMap.getNamedItem(HTML_XML_ATTRIBUTE_NAME); if( aTaskName.equals(tmpNameNode.getNodeValue()) ) { return tmpTaskNode; } } } } //Not found return null; } private void replaceAttributeRequiredInXMLTaskNodeWithAttributeRequiredInHTMLNode(Node aTargetTaskNode, Node aSourceTaskNode) { Node tmpStructureNode = getChildNodeNamedWithTypeFromNode( XDOC_XML_TAG_STRUCTURE, Node.ELEMENT_NODE, aTargetTaskNode ); if(tmpStructureNode != null ) { Node tmpTargetAttributesNode = getChildNodeNamedWithTypeFromNode(XDOC_XML_TAG_ATTRIBUTES, Node.ELEMENT_NODE, tmpStructureNode); if(tmpTargetAttributesNode != null ) { Vector tmpTargetAttributesVector = getAttributeNodesFromXMLAttributesNode(tmpTargetAttributesNode); Vector tmpSourceAttributesVector = getAttributeNodesFromHTMLTaskNode(aSourceTaskNode); //Iterate over all the attributes in the targetTaskNode for(int i=0; i < tmpTargetAttributesVector.size(); ++i) { Node tmpAttributeNode = (Node)tmpTargetAttributesVector.get(i); replaceAttributeRequiredInAttributeNodeWithValueFoundInNodeVector(tmpAttributeNode, tmpSourceAttributesVector); } } } } private void replaceAttributeRequiredInAttributeNodeWithValueFoundInNodeVector(Node aTargetAttributeNode, Vector aSourceAttributeVector) { NamedNodeMap tmpTargetNamedNodeMap = aTargetAttributeNode.getAttributes(); String tmpTargetAttributeName = tmpTargetNamedNodeMap.getNamedItem(XDOC_XML_TAG_NAME).getNodeValue(); String tmpSourceAttributeName = null; String tmpSourceRequiredValue = null; for(int i=0; i < aSourceAttributeVector.size(); ++i) { Node tmpSourceAttributeNode = (Node)aSourceAttributeVector.get(i); NamedNodeMap tmpSourceAttributeNamedNodeMap = tmpSourceAttributeNode.getAttributes(); tmpSourceAttributeName = tmpSourceAttributeNamedNodeMap.getNamedItem(HTML_XML_ATTRIBUTE_NAME).getNodeValue(); //If the Attribute Name is the same we replace the REQUIRED Value if(tmpTargetAttributeName.equals(tmpSourceAttributeName) ){ tmpSourceRequiredValue = tmpSourceAttributeNamedNodeMap.getNamedItem(HTML_XML_ATTRIBUTE_REQUIRED).getNodeValue(); //Set the Vaule to the on we just got. tmpTargetNamedNodeMap.getNamedItem(XDOC_XML_TAG_REQUIRED).setNodeValue(tmpSourceRequiredValue); } } } private Vector getAttributeNodesFromXMLAttributesNode(Node anXMLAttributesNode){ Vector allAttributes = new Vector(); NodeList tmpList = anXMLAttributesNode.getChildNodes(); for(int i = 0; i<tmpList.getLength(); ++i) { Node tmpNode = tmpList.item(i); if(tmpNode.getNodeType() == Node.ELEMENT_NODE && XDOC_XML_TAG_ATTRIBUTE.equals(tmpNode.getNodeName()) ) { allAttributes.add(tmpNode); } } return allAttributes; } private Vector getAttributeNodesFromHTMLTaskNode(Node anHTTP_XML_TaskNode) { Vector tmpVector = new Vector(); NodeList tmpList = anHTTP_XML_TaskNode.getChildNodes(); for(int i = 0; i < tmpList.getLength(); ++i) { Node tmpNode = tmpList.item(i); if(tmpNode.getNodeType() == Node.ELEMENT_NODE && HTML_XML_TAG_ATTRIBUTE.equals(tmpNode.getNodeName()) ) { tmpVector.add(tmpNode); } } return tmpVector; } /** * Returns the ChildNode of the node defined by the Arguments. The * first child found matching the criterias is returned. * * @param aNodeName The Name of the Node to return. * @param aType The Type of the node @see Node * @param aParentNode The Node to get the child from * * @return The First Child Node found matching the criterias, * or null if none is found. */ private Node getChildNodeNamedWithTypeFromNode(String aName, short aNodeType, Node aNode ) { NodeList tmpNodeList = aNode.getChildNodes(); for(int i=0; i<tmpNodeList.getLength(); ++i ) { Node tmpNode = tmpNodeList.item(i); if( (tmpNode.getNodeType() == aNodeType) && aName.equals(tmpNode.getNodeName()) ) { return tmpNode; } } //Not found return null; } /** * Returns the (DOM) document as a result of parsing the file with the * specified file name. * <P> * The file will be loaded as resource, thus must begin with '/' and must * be relative to the classpath. */ private Document parseFile(String aFileName) { Document tempDocument = null; DocumentBuilderFactory tempFactory = DocumentBuilderFactory.newInstance(); tempFactory.setIgnoringComments(true); tempFactory.setIgnoringElementContentWhitespace(true); tempFactory.setCoalescing(true); try { DocumentBuilder tempDocBuilder = tempFactory.newDocumentBuilder(); URL tempURL = getClass().getResource(aFileName); InputSource tempInputSource = new InputSource(tempURL.toExternalForm()); tempDocument = tempDocBuilder.parse(tempInputSource); } catch (ParserConfigurationException e) { AntUIPlugin.log(e); } catch (IOException ioException) { AntUIPlugin.log(ioException); } catch (SAXException saxException) { AntUIPlugin.log(saxException); } return tempDocument; } /** * This function writes the XMLDocument to the specified file. * @param aFileName The filename to which the XMLDocument should be written. */ public void writeXMLDocumentToFile(String aFileName) { // try { // XmlDocument xmlDocument = (XmlDocument)xdocXMLDocument; // xmlDocument.write(new FileWriter(aFileName), "UTF-8"); //$NON-NLS-1$ // } // catch(IOException ioe) { // System.out.println(MessageFormat.format(AntEditorToolsMessages.getString("TaskXMLFileMerger.Could_not_print"), new String[]{ioe.toString()})); //$NON-NLS-1$ // } } public static void main(String[] args) { TaskXMLFileMerger tmpTaskXMLFileMerger = new TaskXMLFileMerger(); tmpTaskXMLFileMerger.runReplaceAttributeRequiredProcess(); tmpTaskXMLFileMerger.writeXMLDocumentToFile("src\\anttasks_1.5b.xml"); //$NON-NLS-1$ } }